// pages/test/index.js

const app = getApp()

const getToken = require("../../utils/token").getToken
const SpeechRecognition = require("../../utils/sr")
const sleep = require("../../utils/util").sleep

const SpeechSynthesizer = require("../../utils/tts")
const formatTime = require("../../utils/util").formatTime
const fs = wx.getFileSystemManager()

Page({

  /**
   * 页面的初始数据
   */
  data: {
    show: true,
    step: 0, // 第几个问题
    countdown: 3, // 回到倒计时，秒
    stResult: "",
    sr: {},
    srStart: false,
    tts: {},
    ttsText: "",
    videoSrc: "",
    qus: [
      '第一个问题？请回答“是”或“否”？',
      '第二个问题？请回答“是”或“否”？',
      '第三个问题？请回答“是”或“否”？'
    ]
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: async function(options) {
    //调用设置相机大小的方法
    this.setCameraSize();
    this.ctxCamera = wx.createCameraContext();

    try {
      this.data.token = await getToken(app.globalData.AKID,
        app.globalData.AKKEY)
    } catch (e) {
      console.log("error on get token:", JSON.stringify(e))
      return
    }

    let tts = new SpeechSynthesizer({
      url: app.globalData.URL,
      appkey: app.globalData.APPKEY,
      token: this.data.token
    })

    tts.on("meta", (msg) => {
      console.log("Client recv metainfo:", msg)
    })

    tts.on("data", (msg) => {
      console.log(`recv size: ${msg.byteLength}`)
      //console.log(dumpFile.write(msg, "binary"))
      if (this.data.saveFile) {
        try {
          fs.appendFileSync(
            this.data.saveFile,
            msg,
            "binary"
          )
          console.log(`append ${msg.byteLength}`)
        } catch (e) {
          console.error(e)
        }
      } else {
        console.log("save file empty")
      }
    })

    tts.on("completed", async (msg) => {
      console.log("Client recv completed:", msg)
      await sleep(500)
      fs.close({
        fd: this.data.saveFd,
        success: (res) => {
          let ctx = wx.createInnerAudioContext()
          ctx.autoplay = true
          ctx.src = this.data.saveFile
          ctx.onPlay(() => {
            console.log('start playing..')
          })
          ctx.onError((res) => {
            console.log(res.errMsg)
            console.log(res.errCode)
            fs.unlink({
              filePath: this.data.saveFile,
              success: (res) => {
                console.log(`remove ${this.data.saveFile} done`)
                this.data.saveFile = null
                this.data.saveFd = null
              },
              failed: (res) => {
                console.log("remove failed:" + res.errMsg)
              }
            })
          })
          ctx.onEnded((res) => {
            console.log("play done...")

            /** 开始 问题回答完后，做出相应的处理 */
            this.data.sr.start(sr.defaultStartParams())
            
            this.countdownFun(this.data.countdown)
            sleep(this.data.countdown * 1000)
              .then(() => {
                this.data.sr.close()

                // 下一个问题
                if (this.data.step < this.data.qus.length) {
                  this.setData({
                    countdown: 3
                  })
                  this.onStartQus()
                } else {
                  this.stopShootVideo()
                }
                // 等于表示，都正确，上传到oss
                if (this.data.step === this.data.qus.length) {

                }

              })
            /** 结束 问题回答完后，做出相应的 */

            fs.unlink({
              filePath: this.data.saveFile,
              success: (res) => {
                console.log(`remove ${this.data.saveFile} done`)
                this.data.saveFile = null
                this.data.saveFd = null
              },
              failed: (res) => {
                console.log("remove failed:" + res.errMsg)
              }
            })
          })
        },
        fail: (res) => {
          console.log("saved file error:" + res.errMsg)
        }
      })
    })

    tts.on("closed", () => {
      console.log("Client recv closed")
    })

    tts.on("failed", (msg) => {
      console.log("Client recv failed:", msg)
    })
    this.data.tts = tts

    wx.getRecorderManager().onFrameRecorded((res) => {
      if (res.isLastFrame) {
        console.log("record done")
      }
      if (this.data.sr && this.data.srStart) {
        console.log("send " + res.frameBuffer.byteLength)
        this.data.sr.sendAudio(res.frameBuffer)
      }
    })
    wx.getRecorderManager().onStart(() => {
      console.log("start recording...")
    })
    wx.getRecorderManager().onStop((res) => {
      console.log("stop recording...")
      if (res.tempFilePath) {
        wx.removeSavedFile({
          filePath: res.tempFilePath
        })
      }
    })
    wx.getRecorderManager().onError((res) => {
      console.log("recording failed:" + res)
    })

    try {
      this.data.token = await getToken(app.globalData.AKID,
        app.globalData.AKKEY)
    } catch (e) {
      console.log("error on get token:", JSON.stringify(e))
      return
    }
    let sr = new SpeechRecognition({
      url: app.globalData.URL,
      appkey: app.globalData.APPKEY,
      token: this.data.token
    })

    sr.on("started", (msg) => {
      console.log("Client recv started")
      this.setData({
        srResult: msg
      })
    })

    sr.on("changed", (msg) => {
      console.log("Client recv changed:", msg)
      this.setData({
        srResult: msg
      })
    })

    sr.on("completed", (msg) => {
      console.log("Client recv completed:", msg)
      this.setData({
        srResult: msg
      })
    })

    sr.on("closed", () => {
      console.log("Client recv closed")
    })

    sr.on("failed", (msg) => {
      console.log("Client recv failed:", msg)
      this.setData({
        srResult: msg
      })
    })

    this.data.sr = sr
  },

  setCameraSize() {
    //获取设备信息
    const res = wx.getSystemInfoSync();
    //获取屏幕的可使用宽高，设置给相机
    this.setData({
      cameraHeight: res.windowHeight,
      cameraWidth: res.windowWidth
    })
    console.log(res)
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  },
  // 倒计时
  countdownFun(count) {
    const countdownTimer = setInterval(() => {
      count -= 1;
      this.setData({
        countdown: count
      });
      if (count <= 0) {
        clearInterval(countdownTimer); // 清除interval以停止倒计时
      }
    }, 1000);
  },

  audiotts() {
    let save = formatTime(new Date()) + ".wav"
    let savePath = wx.env.USER_DATA_PATH + "/" + save
    console.log(`save to ${savePath}`)
    fs.open({
      filePath: savePath,
      flag: "a+",
      success: async (res) => {
        console.log(`open ${savePath} done`)
        this.data.saveFd = res.fd
        this.data.saveFile = savePath
        let param = this.data.tts.defaultStartParams()
        param.text = this.data.ttsText
        param.voice = "aixia"
        try {
          await this.data.tts.start(param)
          console.log("tts done")
        } catch (e) {
          console.log("tts start error:" + e)
        }
      },
      fail: (res) => {
        console.log(`open ${savePath} failed: ${res.errMsg}`)
      }
    })
  },
  // 操作问题，
  onStartQus() {
    this.setData({
      show: false
    })

    this.setData({
      ttsText: this.data.qus[this.data.step]
    })
    this.audiotts()
    this.data.step++;
  },
  OnClick() {
    this.onStartQus();
    this.startShootVideo();
  },

  startShootVideo() {
    this.setData({
      videoSrc: ''
    })

    console.log("========= 调用开始录像 ===========")
    let that = this
    this.ctxCamera.startRecord({
      timeoutCallback: () => {},
      success: (res) => {
        wx.showToast({
          title: '开始录制',
          icon: 'none'
        })
      },
      fail() {
        wx.showToast({
          title: '录像失败',
          icon: 'none'
        })
        console.log("========= 调用开始录像失败 ===========")
      }
    })
  },
  stopShootVideo() {
    wx.hideLoading();
    // console.log("========= 调用结束录像 ===========")
    this.ctxCamera.stopRecord({
      compressed: true, //压缩视频
      success: (res) => {
        console.log(res)
        this.setData({
          videoSrc: res.tempVideoPath
        })
      },
      fail() {
        wx.showToast({
          title: '录像失败',
          icon: 'none',
          duration: 4000
        })
        console.log("========= 调用结束录像失败 ===========")
      }
    })
  },
})